package br.edu.ufcg.splab.io;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.UUID;

import org.jgrapht.UndirectedGraph;
import org.jgrapht.graph.DefaultEdge;

import br.edu.ufcg.splab.core.InterfaceEdge;
import br.edu.ufcg.splab.core.InterfaceGraph;
import br.edu.ufcg.splab.core.InterfaceVertex;
import br.edu.ufcg.splab.generator.TestCase;
import br.edu.ufcg.splab.util.MapFaultAndTestSuite;

public class TGFWriter {
	protected final String EOL = System.getProperty("line.separator");


	public void write(InterfaceGraph graph, String filepath){
		try {
			
			BufferedWriter bufferedTGF =  new BufferedWriter(new FileWriter(new File(filepath)));
			
			bufferedTGF.append(graph.getRoot().getLabel() + " " + graph.getRoot().getLabel() + EOL);
			Set<Entry<UUID, InterfaceVertex>> set =  graph.getStates().entrySet();
			Iterator<Entry<UUID, InterfaceVertex>> it = set.iterator();
			while(it.hasNext()){
				InterfaceVertex vertex = it.next().getValue();
				if(!vertex.getLabel().equals(graph.getRoot().getLabel())){
					bufferedTGF.append(vertex.getLabel() + " " + vertex.getLabel() + EOL);
				}
			}
			bufferedTGF.append("#" + EOL);
			for(InterfaceEdge edge : graph.getEdges()){
				bufferedTGF.append(edge.getFrom().getLabel() + " " + edge.getTo().getLabel() + " " + edge.getLabel() + " [" + edge.getType().toString() + "]" + EOL);
			}
			bufferedTGF.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void write(UndirectedGraph<String, DefaultEdge> graph, String filepath){
		try {			
			BufferedWriter bufferedTGF =  new BufferedWriter(new FileWriter(new File(filepath)));
			Set<String> vertices = graph.vertexSet();
			for(String vertex: vertices){
				bufferedTGF.append(vertex + " " + vertex + EOL);
			}
			bufferedTGF.append("#" + EOL);
			Set<DefaultEdge> edges = graph.edgeSet();
			for(DefaultEdge edge: edges){
				String edge_str = edge.toString().trim();
				Scanner scanner = new Scanner(edge_str);
				scanner.useDelimiter(" : ");
				String edge1 = scanner.next().trim();
				String edge2 = scanner.next().trim();
				bufferedTGF.append(edge1.substring(1, edge1.length()) + " " + edge2.substring(0, edge2.length()-1) + EOL);
				scanner.close();
			}
			bufferedTGF.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void writeAllCliques(Collection<Set<TestCase>> allCliques, MapFaultAndTestSuite map, String filepath){
		try {		
			BufferedWriter bufferedTGF =  new BufferedWriter(new FileWriter(new File(filepath)));
			
			Map<Integer, Map<TestCase, Integer>> mapTemp = new HashMap<Integer, Map<TestCase, Integer>>();
			List<Set<TestCase>> list = new ArrayList<Set<TestCase>>(allCliques);
			int contDefect = 1;
			int contTestCase = 1;
			for(Set<TestCase> set: list){
				List<TestCase> listTC = new ArrayList<TestCase>(set);
				for(TestCase tc: listTC){
					if(mapTemp.containsKey(contDefect)){
						Map<TestCase, Integer> mapTC = mapTemp.get(contDefect);
						mapTC.put(tc, contTestCase);
						bufferedTGF.append(contTestCase + " " + map.getValueTestCase(tc) + EOL);
					}else{
						Map<TestCase, Integer> mapTC = new HashMap<TestCase, Integer>();
						mapTC.put(tc, contTestCase);
						mapTemp.put(contDefect, mapTC);
						bufferedTGF.append(contTestCase + " " + map.getValueTestCase(tc) + EOL);
					}
					contTestCase++;
				}
				contDefect++;
			}
			
			bufferedTGF.append("#" + EOL);
			
			contDefect = 1;
			for(Set<TestCase> set: list){
				List<TestCase> listTC = new ArrayList<TestCase>(set);				
				for(int i = 0; i < listTC.size() - 1; i++){
					for(int j = i + 1; j < listTC.size(); j++){
						bufferedTGF.append(mapTemp.get(contDefect).get(listTC.get(i)) + " " + mapTemp.get(contDefect).get(listTC.get(j))+ EOL);
					}
				}
				contDefect++;
			}
			
			bufferedTGF.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
